package demo.netty.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Hello world!
 *
 * @author 14241
 */
public class AIOServer {

    private static ConcurrentHashMap<String, AsynchronousSocketChannel> concurrentHashMap = new ConcurrentHashMap<>();


    public static void main(String[] args) throws IOException, InterruptedException {
        initServer();
        Thread.sleep(Integer.MAX_VALUE);
    }

    public static void initServer() {
        try {
            AsynchronousServerSocketChannel asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
            asynchronousServerSocketChannel.bind(new InetSocketAddress(9001));
            asynchronousServerSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
                @Override
                public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
                    asynchronousServerSocketChannel.accept(attachment,this);
                    try {
                        SocketAddress remoteAddress = socketChannel.getRemoteAddress();
                        System.out.println("客户端："+ remoteAddress +"已经上线");
                        concurrentHashMap.forEach((item, value) -> {
                            value.write(ByteBuffer.wrap((("客户端" + remoteAddress + "上线").getBytes())));
                        });
                        concurrentHashMap.put(remoteAddress.toString(),socketChannel);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    ByteBuffer allocate = ByteBuffer.allocate(1024);
                    //设置读取信息的回调函数
                    socketChannel.read(allocate, allocate, new CompletionHandler<Integer, ByteBuffer>() {
                        @Override
                        public void completed(Integer key, ByteBuffer attachment) {
                            String msg = new String(attachment.array(),0,key);
                            concurrentHashMap.forEach((item, value) -> {
                                try {
                                    value.write(ByteBuffer.wrap((((value == socketChannel ? "自己" : socketChannel.getLocalAddress()) + ":"+msg).getBytes())));
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            });
                        }
                        @Override
                        public void failed(Throwable exc, ByteBuffer attachment) {

                        }
                    });
                }

                @Override
                public void failed(Throwable exc, Object attachment) {

                }

            });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
